package br.indt.framework.ui.common;

import java.util.Vector;

import javax.microedition.lcdui.Graphics;

/**
 * Composite component that can group Widgets to display in
 * vertical or horizontal orientation.
 * 
 * @author Nokia Institute of Technology
 *
 */
public class LayoutPanel extends Widget implements WidgetContainer {

	private boolean ignoreInnerWidgets = false;	
	private boolean vertical = false;
	private boolean autoHeightSize = true;
	private int selectedBackgroundColor = 0;
	private int selectedTextColor = 0;
	private ObjectActionListener actionListener = null;
	private int heightSet;	
	
	private Vector widgets = new Vector();
	
	public LayoutPanel(String name) {
		super(name);		
	}
	
	public LayoutPanel(String name, boolean vertical) {
		super(name);
		this.vertical = vertical;
	}
	
	public LayoutPanel(String name, boolean vertical, boolean autoSize) {
		super(name);
		this.vertical = vertical;
		this.autoHeightSize = autoSize;
	}	
	
	public boolean isVertical() {
		return vertical;
	}

	public void setVertical(boolean vertical) {
		this.vertical = vertical;
	}

	public boolean isAutoHeightSize() {
		return autoHeightSize;
	}

	public void setAutoHeightSize(boolean autoHeightSize) {
		this.autoHeightSize = autoHeightSize;
		calculateHeight();
	}
	
	public void setHeight(int height) {
		heightSet = height;
		autoHeightSize = false;
		calculateHeight();
	}
	
	public ObjectActionListener getActionListener() {
		return actionListener;
	}

	public void setActionListener(ObjectActionListener actionListener) {
		this.actionListener = actionListener;
	}

	public void setMargin(int left, int top, int right, int bottom) {
		super.setMargin(left, top, right, bottom);
		calculateHeight();
	}

	public boolean isIgnoreInnerWidgets() {
		return ignoreInnerWidgets;
	}

	public void setIgnoreInnerWidgets(boolean ignoreInnerWidgets) {
		this.ignoreInnerWidgets = ignoreInnerWidgets;
	}

	public int getSelectedBackgroundColor() {
		return selectedBackgroundColor;
	}

	public void setSelectedBackgroundColor(int selectedBackgroundColor) {
		this.selectedBackgroundColor = selectedBackgroundColor;
	}
	
	public int getSelectedTextColor() {
		return selectedTextColor;
	}

	public void setSelectedTextColor(int selectedTextColor) {
		this.selectedTextColor = selectedTextColor;
	}

	public void add(Widget widget){
		if (widget == null) {
			throw new IllegalArgumentException("widget cannot be null");
		}
		widgets.addElement(widget);
		calculateHeight();
	}
	
	public void remove(Widget widget) {
		widgets.removeElement(widget);
		calculateHeight();
	}
	
	public void removeAll() {
		widgets.removeAllElements();		
	}
	
	public boolean hasWidgets() {
		return !widgets.isEmpty();
	}
	
	public void pressFire() { 
		click(0, 0);
	}	
	
	public void click(int x, int y) {
		if (ignoreInnerWidgets && actionListener != null) { 
			actionListener.objetcClicked(x, y, this);
			setPressedDownState(false);
		}
	}
	
	public void longPressed(int x, int y) {		
	}
	
	public void paint(Graphics g, int x, int y, int maxWidth, int maxHeight) {		
		
		if (maxHeight <= 0) {
			maxHeight = getHeight();
		}
		
		g.setClip(x + leftMargin, y + topMargin, maxWidth - rightMargin, maxHeight - bottomMargin - topMargin);
		
		if (backgroundImage != null) {
			g.drawImage(backgroundImage, x + leftMargin, y + topMargin, Graphics.TOP | Graphics.LEFT);
		}
		
		int paintBackgroungColor = ignoreInnerWidgets && pressedDown ? selectedBackgroundColor : backgroundColor;
		
		if (paintBackgroungColor > 0) { 
			g.setColor(paintBackgroungColor);
			g.fillRect(x + leftMargin, y + topMargin, getWidth() - rightMargin, getHeight() - bottomMargin - topMargin);
		}
		
		y += topMargin;
		x += leftMargin;
		
		for (int i = 0; i < widgets.size(); i++) {
			Widget widget = (Widget)widgets.elementAt(i);
						
			widget.setPosX(x);
			widget.setPosY(y);
			
			if (widget.getWidth() <= 0) {
				widget.setWidth(maxWidth - x - rightMargin);
			}
			
			int originalTextColor = 0; 
			boolean canHighlightLabel = ignoreInnerWidgets && pressedDown && widget instanceof Label && selectedTextColor > 0;
			
			if (canHighlightLabel) {
				originalTextColor = ((Label)widget).getTextColor();
				((Label)widget).setTextColor(selectedTextColor);
			}
			
			if (ignoreInnerWidgets) {
				widget.setPressedDownState(pressedDown);
			}
			
			widget.paint(g, x, y, getWidth() - rightMargin, getHeight() - bottomMargin);
			
			if (canHighlightLabel) {
				((Label)widget).setTextColor(originalTextColor);
			}			
			
			if (vertical) {
				y += widget.getHeight();
			} else {
				x += widget.getWidth();
				if (widget instanceof LayoutPanel) {
					x += widget.getLeftMargin();
				}
			}
		}
	}
	
	private void calculateHeight() {
		if (autoHeightSize) {
			height = 0;
			for (int i = 0; i < widgets.size(); i++) {
				Widget widget = (Widget)widgets.elementAt(i);
				
				if (vertical) {
					height += widget.getHeight();
				} else if (widget.getHeight() > height) {
					height = widget.getHeight(); 
				}
			}
		} else {
			height = heightSet;
		}
		
		height += topMargin + bottomMargin;
	}

	public Widget getWidgetAt(int x, int y) {
		
		for (int i = 0; i < widgets.size() && !ignoreInnerWidgets; i++) {
			Widget widget = (Widget)widgets.elementAt(i);
			
			if (x >= widget.getPosX() + widget.getLeftMargin() && x <= widget.getPosX() + widget.getWidth() - widget.getRightMargin()) {
				if (y >= widget.getPosY() + widget.getTopMargin() && y <= widget.getPosY() + widget.getHeight() - widget.getBottomMargin()) {
					if (widget instanceof WidgetContainer) {
						Widget innerWidget = ((WidgetContainer)widget).getWidgetAt(x, y);
						if (innerWidget != null) {
							widget = innerWidget;
						}
					}
					
					return widget;
				}
			}
		}
		
		return null;
	}

	public Widget getWidgetByName(String name) {
		for (int i = 0; i < widgets.size() && !ignoreInnerWidgets; i++) {
			
			Widget widget = (Widget)widgets.elementAt(i);
			
			if (widget.getName().equals(name)) {
				
				return widget;
				
			} else if (widget instanceof WidgetContainer) {
				
				Widget innerWidget = ((WidgetContainer)widget).getWidgetByName(name);
				if (innerWidget != null) {
					return innerWidget;
				}
				
			}
		}
		
		return null;
	}
}
